package com.example.app.service.impl;

import com.example.app.dto.*;
import com.example.app.entity.User;
import com.example.app.entity.UserProfile;
import com.example.app.exception.InvalidPasswordException;
import com.example.app.exception.UserAlreadyExistsException;
import com.example.app.exception.UserNotFoundException;
import com.example.app.repository.UserProfileRepository;
import com.example.app.repository.UserRepository;
import com.example.app.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Optional;

@Service
public class UserServiceImpl implements UserService {
    private final UserRepository userRepository;
    private final UserProfileRepository userProfileRepository;
    private final PasswordEncoder passwordEncoder;
    private static final int MIN_BIRTH_YEAR = 1900;
    private static final int MAX_BIRTH_YEAR = LocalDate.now().getYear() - 5;
    private static final int MIN_HEIGHT = 50;
    private static final int MAX_HEIGHT = 250;
    @Autowired
    public UserServiceImpl(UserRepository userRepository,
                           UserProfileRepository userProfileRepository,
                           PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.userProfileRepository = userProfileRepository;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    @Transactional
    public User registerUser(RegisterRequest request) throws UserAlreadyExistsException {
        // 检查手机号是否已注册
        if (userRepository.existsByPhone(request.getPhone())) {
            throw new UserAlreadyExistsException("该手机号已注册");
        }

        // 创建用户
        User user = new User();
        user.setPhone(request.getPhone());
        user.setPassword(passwordEncoder.encode(request.getPassword()));
        user.setCreatedAt(LocalDateTime.now());
        user = userRepository.save(user);

        // 创建用户档案
        UserProfile profile = new UserProfile();
        profile.setUser(user);
        profile.setName(request.getName());
        userProfileRepository.save(profile);

        return user;
    }

    @Override
    public User authenticateUser(LoginRequest request) throws UserNotFoundException {
        // 查找用户
        User user = userRepository.findByPhone(request.getPhone())
                .orElseThrow(() -> new UserNotFoundException("用户不存在"));

        // 验证密码
        if (!passwordEncoder.matches(request.getPassword(), user.getPassword())) {
            throw new UserNotFoundException("密码错误");
        }

        return user;
    }

    @Override
    @Transactional
    public void deleteUser(Long userId) throws UserNotFoundException {
        // 查找用户
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new UserNotFoundException("用户不存在"));

        // 删除用户及关联档案
        userRepository.delete(user);
    }

    @Override
    @Transactional
    public void updatePassword(Long userId, PasswordUpdateRequest request) throws UserNotFoundException {
        // 查找用户
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new UserNotFoundException("用户不存在"));
        // 验证原密码

        if (!passwordEncoder.matches(request.getOldPassword(), user.getPassword())) {
            throw new InvalidPasswordException("原密码不正确"); // 修改为正确的异常类型
        }
        // 更新密码
        user.setPassword(passwordEncoder.encode(request.getNewPassword()));
        userRepository.save(user);
    }
    @Override
    @Transactional
    public void updateName(Long userId, NameUpdateRequest request) throws UserNotFoundException {
        // 查找用户档案
        UserProfile profile = userProfileRepository.findByUserUserId(userId)
                .orElseThrow(() -> new UserNotFoundException("用户档案不存在"));

        // 更新姓名
        profile.setName(request.getNewName());
        userProfileRepository.save(profile);
    }

    @Override
    @Transactional(readOnly = true)
    public UserProfileDTO getUserProfile(Long userId) throws UserNotFoundException {
        // 获取用户档案
        UserProfile profile = userProfileRepository.findByUserUserId(userId)
                .orElseThrow(() -> new UserNotFoundException("用户档案不存在"));

        // 转换为DTO
        UserProfileDTO dto = new UserProfileDTO();
        dto.setName(profile.getName());
        dto.setGender(profile.getGender());
        dto.setBirthYear(profile.getBirthYear());
        dto.setOccupation(profile.getOccupation());
        dto.setHeight(profile.getHeight());
        dto.setHealthDescription(profile.getHealthDescription());

        // 计算年龄
        if (profile.getBirthYear() != null) {
            int currentYear = LocalDate.now().getYear();
            dto.setAge(currentYear - profile.getBirthYear());
        }

        return dto;
    }

    @Override
    @Transactional
    public UserProfileDTO updateUserProfile(Long userId, UserProfileDTO request)
            throws UserNotFoundException {

        // 获取用户信息（用于验证）
        User user = userRepository.findById(userId)
                .orElseThrow(() -> new UserNotFoundException("用户不存在"));

        // 获取现有档案
        Optional<UserProfile> existingProfile = userProfileRepository.findByUserUserId(userId);
        UserProfile profile;

        if (existingProfile.isPresent()) {
            profile = existingProfile.get();
        } else {
            // 如果不存在则创建新档案
            profile = new UserProfile();
            profile.setUser(user);
            // 设置默认值
            profile.setName(user.getProfile().getName()); // 从用户名字段获取默认值
        }

        // 验证并更新字段
        validateProfileRequest(request);

        // 更新可修改字段
        if (request.getName() != null && !request.getName().isBlank()) {
            profile.setName(request.getName());
        }
        if (request.getGender() != null && !request.getGender().isBlank()) {
            profile.setGender(request.getGender());
        }
        if (request.getBirthYear() != null) {
            profile.setBirthYear(request.getBirthYear());
        }
        if (request.getOccupation() != null && !request.getOccupation().isBlank()) {
            profile.setOccupation(request.getOccupation());
        }
        if (request.getHeight() != null) {
            profile.setHeight(request.getHeight());
        }
        if (request.getHealthDescription() != null) {
            profile.setHealthDescription(request.getHealthDescription());
        }

        // 保存更新
        userProfileRepository.save(profile);

        // 返回更新后的DTO
        return getUserProfile(userId);
    }

    // 验证用户档案请求的辅助方法
    private void validateProfileRequest(UserProfileDTO request) {
        // 验证出生年份
        if (request.getBirthYear() != null &&
                (request.getBirthYear() < MIN_BIRTH_YEAR || request.getBirthYear() > MAX_BIRTH_YEAR)) {
            throw new IllegalArgumentException("出生年份无效");
        }

        // 验证身高
        if (request.getHeight() != null &&
                (request.getHeight() < MIN_HEIGHT || request.getHeight() > MAX_HEIGHT)) {
            throw new IllegalArgumentException("身高无效");
        }

        // 验证姓名长度
        if (request.getName() != null && request.getName().length() > 50) {
            throw new IllegalArgumentException("姓名过长");
        }

        // 验证健康描述长度
        if (request.getHealthDescription() != null &&
                request.getHealthDescription().length() > 1000) {
            throw new IllegalArgumentException("健康描述过长");
        }
    }
}